package main

import (
	"fmt"

	"github.com/cheggaaa/pb/v3"
	log "github.com/sirupsen/logrus"
	"github.com/twang2218/herbs/common"
	"github.com/twang2218/herbs/crawler"
	"github.com/twang2218/herbs/processor"
	"github.com/urfave/cli/v2"
)

func actionCrawlHerbs(c *cli.Context) error {
	var herbs common.Herbs

	crawler := crawler.NewHerbCrawler()
	bar := pb.StartNew(10)
	crawler.AddOnHerbListener(func(h common.Herb) {
		herbs.Add(h)
		if len(herbs)%100 == 0 {
			log.Infof("-----========< 已下载 %d 中药药材 (%d / %d) >=======------", len(herbs), crawler.PageVisited, crawler.PageTotal)
			if err := common.SaveToJSON(c.String("output"), herbs); err != nil {
				log.Fatal(err)
			}
		}
		//	update progress bar
		bar.SetTotal(int64(crawler.PageTotal))
		bar.SetCurrent(int64(crawler.PageVisited))
	})
	crawler.Collect()
	bar.Finish()
	log.Infof("总共得到 %d 种中药药材。", len(herbs))

	//	排序
	herbs.Sort()

	//	将最终结果写入 JSON
	if err := common.SaveToJSON(c.String("output"), herbs); err != nil {
		return err
	}

	return nil
}

func actionCrawlPrescription(c *cli.Context) error {
	var pres common.Prescriptions

	crawler := crawler.NewPrescriptionCrawler()
	bar := pb.StartNew(10)
	crawler.AddOnPrescriptionListener(func(p common.Prescription) {
		pres.Add(p)
		// log.Debug(".")
		// // log.Infof("【%s】 %s", p.Name, p.Link)
		if len(pres)%100 == 0 {
			log.Infof("-----========< 已下载 %d 中药方剂 (%d / %d) >=======------", len(pres), crawler.PageVisited, crawler.PageTotal)
			if err := common.SaveToJSON(c.String("output"), pres); err != nil {
				log.Fatal(err)
			}
			// log.Debugf("分项列表：%+v", crawler.keys)
		}
		//	update progress bar
		bar.SetTotal(int64(crawler.PageTotal))
		bar.SetCurrent(int64(crawler.PageVisited))
	})
	crawler.Collect()
	bar.Finish()
	log.Infof("总共得到 %d 个中药方剂。", len(pres))

	//	排序
	pres.Sort()

	//	将最终结果写入 JSON
	if err := common.SaveToJSON(c.String("output"), pres); err != nil {
		return err
	}

	return nil
}

func actionStats(c *cli.Context) error {
	//	加载药材数据
	var herbs common.Herbs
	if err := herbs.LoadFromJSON(c.String("herb")); err != nil {
		return fmt.Errorf("无法加载数据文件。'%s'", err.Error())
	}
	log.Infof("读取了 %d 味中药药材。", len(herbs))

	//	加载方剂数据
	var pres common.Prescriptions
	if err := pres.LoadFromJSON(c.String("prescription")); err != nil {
		return fmt.Errorf("无法加载数据文件。'%s'", err.Error())
	}
	log.Infof("读取了 %d 个中药方剂。", len(pres))

	processor.Statistics(herbs, pres)

	return nil
}

func actionProcess(c *cli.Context) error {
	//	加载药材数据
	var herbs common.Herbs
	if err := herbs.LoadFromJSON(c.String("herb")); err != nil {
		return fmt.Errorf("无法加载数据文件。'%s'", err.Error())
	}
	log.Infof("读取了 %d 味中药药材。", len(herbs))

	//	加载方剂数据
	var pres common.Prescriptions
	if err := pres.LoadFromJSON(c.String("prescription")); err != nil {
		return fmt.Errorf("无法加载数据文件。'%s'", err.Error())
	}
	log.Infof("读取了 %d 个中药方剂。", len(pres))

	processor.Process(herbs, pres)

	return nil
}
